#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <pthread.h>
#include "thread_pool.h"

typedef struct Filename
{
    char srcpath[500];
    char destpath[500];
}FILENAME;
void* copy_file(void* arg);
void copy_dir(const char* srcpath, const char* destpath);

ThreadPool* pool = NULL;//线程池地址


int main(int argc, char** argv)
{
    if (argc == 3)
    {
        pool = malloc(sizeof(ThreadPool));

        init_pthread_pool(pool, 10);
        copy_dir(argv[1], argv[2]);
    }
    else {
        printf("请按照以下格式进行输入：\n");
        printf("例：\n./a.out 123 456 (其中123为源目录，456为目标目录)");
    }
    threadpool_destroy(pool);
    return 0;
}












/**
    copy_file：线程拷贝文件
    @arg:文件路径结构体地址FILENAME
 */
void* copy_file(void* arg)
{
    pthread_detach(pthread_self());//对线程设置分离属性
    FILENAME* filepath = (FILENAME*)arg;

    //1.打开源文件
    int fd_src = open(filepath->srcpath, O_RDONLY);
    if (fd_src == -1)
    {
        perror("open src error");
        exit(1);
    }

    //2.打开目标文件
    int fd_dest = open(filepath->destpath, O_WRONLY | O_CREAT, 0777);
    if (fd_dest == -1)
    {
        perror("open_dest error");
        exit(1);
    }

    //3.不断的读取源文件，并写入目标文件
    char buf[100] = { 0 };
    while (1)
    {
        memset(buf, 0, sizeof(buf));

        //读取源文件数据
        int ret = read(fd_src, buf, sizeof(buf));
        if (ret <= 0)
            break;//读完了/读错了
        write(fd_dest, buf, ret);
    }
    close(fd_src);
    close(fd_dest);
    free(filepath);
}


void copy_dir(const char* srcpath, const char* destpath)
{
    printf("copy file:%s==>%s\n", srcpath, destpath);
    //1.创建目录
    mkdir(destpath, 0777);

    //2.打开源目录
    DIR* dir = opendir(srcpath);
    if (dir == NULL)
    {
        printf("srcpath=%s\n", srcpath);
        perror("opendir error");
        exit(1);
    }

    struct dirent* dirp = NULL;
    char srcfilename[500] = { 0 };
    char destfilename[500] = { 0 };

    //3.读取目录项
    while (dirp = readdir(dir))
    {
        //合成绝对路径
        memset(srcfilename, 0, sizeof(srcfilename));
        memset(destfilename, 0, sizeof(destfilename));
        sprintf(srcfilename, "%s/%s", srcpath, dirp->d_name);
        sprintf(destfilename, "%s/%s", destpath, dirp->d_name);

        //获取文件属性
        struct stat st;
        stat(srcfilename, &st);
        if (S_ISREG(st.st_mode))//如果是文件
        {
            //创建一个线程进行文件拷贝
            FILENAME* filepath = malloc(sizeof(FILENAME));
            strcpy(filepath->srcpath, srcfilename);
            strcpy(filepath->destpath, destfilename);

            add_task(pool, copy_file, (void*)filepath);//创建一个线程进行文件拷贝
        }
        else if (S_ISDIR(st.st_mode))//如果是目录
        {
            if (strcmp(dirp->d_name, ".") != 0 && strcmp(dirp->d_name, "..") != 0)
            {
                copy_dir(srcfilename, destfilename);
            }
        }
    }
}